package com.hua.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hua.common.Response;
import com.hua.common.ResponseCode;
import com.hua.domain.*;
import com.hua.domain.domainVo.CommodityDetailVO;
import com.hua.domain.domainVo.CommodityInfoVo;
import com.hua.domain.domainVo.CommodityVo;
import com.hua.exception.BusinessException;
import com.hua.mapper.*;
import com.hua.service.CommodityInfoService;
import com.hua.util.RedisCache;
import com.hua.util.ResultUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author cl
 * @description 针对表【commodity_info(商品的信息的表)】的数据库操作Service实现
 * @createDate 2022-10-19 11:14:23
 */
@Service
public class CommodityInfoServiceImpl extends ServiceImpl<CommodityInfoMapper, CommodityInfo> implements CommodityInfoService {

    @Resource
    private CommodityInfoMapper commodityInfoMapper;

    @Resource
    private FlavorMapper flavorMapper;

    @Resource
    private ScaleMapper scaleMapper;

    @Resource
    private TeabottomMapper teabottomMapper;

    @Resource
    private MixIngredientsMapper mixIngredientsMapper;

    @Resource
    private RedisCache redisCache;

    @Resource
    private PriceMapper priceMapper;

    @Resource
    private CategoryMapper categoryMapper;


    /**
     * @Description: 获取商品列表
     * @Param: 无
     * @return: Response<List < CommodityInfo>>
     * @Author: 黄燕峰
     */
    @Override
    public Response<Map<String,List<CommodityInfo>>> getCommodityList() {

        Map<String,List<CommodityInfo>> redisResult=redisCache.getCacheMap("AllCommodityList");

        if(redisResult!=null)  return ResultUtils.success(ResponseCode.SUCCESS, redisResult, null);
        List<CommodityInfo> commodityInfos = commodityInfoMapper.selectList(null);

        Map<String,List<CommodityInfo>> map=new HashMap<>();
        categoryMapper.selectList(null).forEach(category -> {
            map.put(category.getCategoryName(),new ArrayList<>());
        });

        commodityInfos.forEach(c->{
            String commodityType = c.getCommodityType();

//            根据商品类型将商品分类
                map.get(commodityType).add(c);

        }) ;
        System.out.println(map);
        redisCache.setCommodityList("AllCommodityList",map);

        return ResultUtils.success(ResponseCode.SUCCESS, map, null);
    }
    
    
    /** 
    * @Description: 获取一个商品的详细信息 
    * @Param: Integer commodityId 
    * @return: Response<CommodityVo>
    * @Author: 黄燕峰
    */



    /**
     * author:feng
     * xiaochengxu
     * @return
     */
    public Response<Map<String,List<CommodityVo>>> getAllCommodityInfoList() {

//      先从redis中获取所有商品信息
        Map<String, List<CommodityVo>> commodityInfo = redisCache.getCacheMapList("commodityInfo");


//        redis缓存判断
        if(commodityInfo.size() != 0) {
            return ResultUtils.success(ResponseCode.SUCCESS, commodityInfo,null);
         }
//       从数据库中获取所有商品信息
         List<CommodityInfo> commodityInfoList = this.list();
//        判断数据库中是否有数据,为空直接返回
        if(commodityInfoList.size()==0){
            throw new BusinessException(ResponseCode.SYSTEM_ERROR,"数据为空!");
        }
//        创建map按商品类型分类存储商品集合
         commodityInfo=new HashMap<>();
//        遍历所有商品,根据商品中取出的flavorId查询temperature,sugar,teabottoms,scales,mixIngredients,将其封装到CommodityVo中
        for (CommodityInfo c :
                commodityInfoList) {
//            从商品中取出的flavorId查询对应的Flavor对象
            Flavor flavor = flavorMapper.selectOne(new LambdaQueryWrapper<Flavor>().eq(Flavor::getFlavorId,c.getFlavorId()));


            List<Scale> scales=null;
            List<Teabottom> teabottoms=null;
            List<String> temperature=null;
            List<String> sugar=null;
            List<BigDecimal> price=null;
            List<MixIngredients> mixIngredients=null;
            if (flavor!=null) {
//            从flavor中取出scaleId封装到数组中
                String[] scaleIdsSpring = flavor.getScaleId().split(",");
                Integer[] scaleIds = new Integer[scaleIdsSpring.length];
                for (int i = 0; i < scaleIdsSpring.length; i++) {
                    scaleIds[i] = Integer.parseInt(scaleIdsSpring[i]);
                }
//            根据数组中的每一个scaleId获取Scale集合
                 scales = scaleMapper.selectByScaleIds(scaleIds);

//            获取商品中不同规格的价格
                List<BigDecimal> list = new ArrayList<>();

                scales.forEach(s -> {
                    Price result = priceMapper.selectOne(new QueryWrapper<Price>().eq("scaleId", s.getScaleId()).eq("commodityId", c.getId()));
                    if (result != null) {
                        list.add(result.getPrice());
                    }
                });
//            对价格进行排序
                price = list.stream().sorted().collect(Collectors.toList());


//            从flavor中取出teaId封装到数组中
                if (flavor.getTeaId()!=null){
                String[] teaIdsSpring = flavor.getTeaId().split(",");

                Integer[] teaId = new Integer[teaIdsSpring.length];
                for (int i = 0; i < teaIdsSpring.length; i++) {
                    teaId[i] = Integer.parseInt(teaIdsSpring[i]);
                }
                    //            根据数组中的每一个teaId获取teaBottom集合
                    teabottoms = teabottomMapper.selectByTeaIds(teaId);
                }else   teabottoms = teabottomMapper.selectByTeaIds(null);





//            从flavor中取出ingredientId封装到数组中
                String[] ingredientIdSpring = flavor.getTeaId().split(",");
                Integer[] ingredientId = new Integer[ingredientIdSpring.length];
                for (int i = 0; i < ingredientIdSpring.length; i++) {
                    ingredientId[i] = Integer.parseInt(ingredientIdSpring[i]);
                }
//            根据数组中的每一个ingredientId获取mixIngredients集合
                 mixIngredients = mixIngredientsMapper.selectByIngredientIds(ingredientId);

//            将temperature分割封装到String集合
                temperature = Arrays.asList(flavor.getTemperature().split(","));
//            将sugar分割封装到String集合
                sugar = Arrays.asList(flavor.getSugar().split(","));
            }

//            将所有上面所有数据封装到CommodityVo对象中
            CommodityVo commodityVo=new CommodityVo();
            commodityVo.setCommodityInfo(c);
            commodityVo.setScales(scales);
            commodityVo.setTeaBottoms(teabottoms);
            commodityVo.setSugar(sugar);
            commodityVo.setPrice(price);

            commodityVo.setTemperature(temperature);
            commodityVo.setMixIngredients(mixIngredients);



//            获取商品的类型
            String commodityType = c.getCommodityType();
//            根据商品类型将商品分类
            if (!commodityInfo.containsKey(commodityType)){
                commodityInfo.put(commodityType,new ArrayList<>());
                commodityInfo.get(commodityType).add(commodityVo);
            }else {
                commodityInfo.get(commodityType).add(commodityVo);
            }

        }

//           将数据缓存到redis中
        redisCache.setCacheMapCommodityInfo("commodityInfo", commodityInfo);

//          返回数据
        return ResultUtils.success(ResponseCode.SUCCESS, commodityInfo,null);
    }


    /**
    * @Description: 获取所有商品
    * @Param: 无
    * @return: Response<Map<String,List<Commodity>>
    * @Author: 黄燕峰
    */









    /**
     * @Author feng
     * @param
     * @return
     */
    @Override
    @Transactional
    public Response<String> insertCategory(CommodityInfoVo commodityInfoVo) {

        CommodityInfo commodityInfo = commodityInfoVo.getCommodityInfo();
        String mixIngredientsIds="";
        String teaBottomIds="";
        String sugarIds="";
        String temperatureIds="";
        String scaleIds="";
        Flavor flavor=new Flavor();
        Map<Integer,BigDecimal> priceMap=new HashMap<>();
        List<Integer> mixIngredientsIdList = commodityInfoVo.getMixIngredientsId();
        List<Integer> teaBottomsIdList = commodityInfoVo.getTeaBottomsId();
        List<String> sugarIdsList = commodityInfoVo.getSugarIds();
        List<String> temperatureIdList = commodityInfoVo.getTemperatureId();
        List<BigDecimal> pricesList = commodityInfoVo.getPrices();

        for (int i = 0; i < mixIngredientsIdList.size(); i++) {
            if (i==mixIngredientsIdList.size()-1) {
                mixIngredientsIds+=mixIngredientsIdList.get(i);
                break;
            }
            mixIngredientsIds+=mixIngredientsIdList.get(i)+",";
        }

        for (int i = 0; i < teaBottomsIdList.size(); i++) {
            if (i==teaBottomsIdList.size()-1) {
                teaBottomIds+=teaBottomsIdList.get(i);
                break;
            }
            teaBottomIds+=teaBottomsIdList.get(i)+",";
        }

        for (int i = 0; i < sugarIdsList.size(); i++) {
            if (i==sugarIdsList.size()-1) {
                sugarIds+=sugarIdsList.get(i);
                break;
            }
            sugarIds+=sugarIdsList.get(i)+",";
        };


        for (int i = 0; i < temperatureIdList.size(); i++) {
            if (i==temperatureIdList.size()-1){
                temperatureIds+=temperatureIdList.get(i);
                break;
            }
            temperatureIds+=temperatureIdList.get(i)+",";
        }

        for (int i = 0; i < pricesList.size(); i++) {
          if ((pricesList.get(i) != null) || (pricesList.get(i)+"" != "")) {
              Integer scaleId = scaleMapper.selectOne(new QueryWrapper<Scale>().eq("scale", i)).getScale();
              priceMap.put(scaleId,pricesList.get(i));
              if ("".equals(scaleIds)) {
                  scaleIds += scaleId;
              } else scaleIds += "," +scaleId;
          }
        };

        flavor.setIngredientId(mixIngredientsIds);
        flavor.setSugar(sugarIds);
        flavor.setTeaId(teaBottomIds);
        flavor.setScaleId(scaleIds);
        flavor.setTemperature(temperatureIds);
        if(flavorMapper.insertByFlavor(flavor)<=0){
            throw new BusinessException(ResponseCode.PARAMS_ERROR,"添加flavor失败~");
        };
        commodityInfo.setFlavorId(flavor.getFlavorId());
        if(commodityInfoMapper.insert(commodityInfo)<=0){
            throw new BusinessException(ResponseCode.PARAMS_ERROR,"添加commodity失败~");
        }

        priceMap.entrySet().forEach(p->{
            Price price=new Price();
            price.setPrice(p.getValue());
            price.setCommodityId(commodityInfo.getId());
            price.setScaleId(p.getKey());
            if(priceMapper.insert(price)<=0){
                throw new BusinessException(ResponseCode.PARAMS_ERROR,"添加price失败~");
            }
        });




            redisCache.deleteObject("commodityInfo");
            redisCache.deleteObject("categories");
            if(!Objects.isNull(commodityInfoVo.getCommodityInfo().getCommodityType())){
                System.out.println("CommodityPriceVo"+commodityInfoVo.getCommodityInfo().getCommodityType());
                redisCache.deleteObject("CommodityPriceVo"+commodityInfoVo.getCommodityInfo().getCommodityType());
            }
            return ResultUtils.success(ResponseCode.SUCCESS,"添加成功");


    }

    /**
     * @author feng
     * @param commodityInfoId
     * @return
     */
    @Override
    @Transactional
    public Response<String> deleteInfoById(CommodityInfo commodityInfoId) {
        if (commodityInfoId.getId()==null) throw new BusinessException(ResponseCode.UPDATE_ERROR, "传入数据为空");
        deleteFlavorAndPrice(commodityInfoMapper.selectOne(new QueryWrapper<CommodityInfo>().eq("id",commodityInfoId)));
        if (commodityInfoMapper.deleteById(commodityInfoId)<=0) throw new BusinessException(ResponseCode.INPUT_ERROR,"删除失败");
        redisCache.deleteObject("commodityInfo");
        redisCache.deleteObject("categories");
        redisCache.deleteObject("AllCommodityList");
        if(!Objects.isNull(commodityInfoId.getCommodityType())){
                redisCache.deleteObject("CommodityPriceVo"+commodityInfoId.getCommodityType());
            }
        return ResultUtils.success(ResponseCode.SUCCESS,"删除成功");



    }





    /**
     * @author hua
     * @param
     * @return
     */
    @Override
    public Response<String> updateInfoById(CommodityInfoVo commodityInfoVo) {

        CommodityInfo commodityInfoUpdateInfo = commodityInfoVo.getCommodityInfo();
        commodityInfoUpdateInfo.setCommodityAddTime(new Date());

        LambdaQueryWrapper<CommodityInfo> queryWrapper
                = new LambdaQueryWrapper<>();
        queryWrapper.eq(CommodityInfo::getId, commodityInfoUpdateInfo.getId());

        Flavor flavor = new Flavor();
        flavor.setFlavorId(commodityInfoUpdateInfo.getFlavorId());
        LambdaQueryWrapper<Flavor> flavorLambdaQueryWrapper
                = new LambdaQueryWrapper<>();
        flavorLambdaQueryWrapper.eq(Flavor::getFlavorId,flavor.getFlavorId());

        if(flavorMapper.update(flavor, flavorLambdaQueryWrapper) > 0 && commodityInfoMapper.update(commodityInfoUpdateInfo, queryWrapper)>0){
            redisCache.deleteObject("commodityInfo");
            redisCache.deleteObject("categories");
            redisCache.deleteObject("AllCommodityList");
            if(!Objects.isNull(commodityInfoVo.getCommodityInfo().getCommodityType())){
                redisCache.deleteObject("CommodityPriceVo"+commodityInfoVo.getCommodityInfo().getCommodityType());
            }
            return ResultUtils.success(ResponseCode.SUCCESS,"更新成功");
        }
        throw new BusinessException(ResponseCode.UPDATE_ERROR,"更新失败");
    }



    /**
     * @Description: 根据商品种类删除所有该种类的商品
     * @Param: String categoryName
     * @return: int
     * @Author: 黄燕峰
     */

    @Override
    @Transactional
    public void delete(String categoryName) {
        if (categoryName==null) return;
        commodityInfoMapper.selectList(new QueryWrapper<CommodityInfo>().eq("commodityType",categoryName)).forEach(commodityInfo -> {
            deleteFlavorAndPrice(commodityInfo);
        });
        if(commodityInfoMapper.selectList(new QueryWrapper<CommodityInfo>().eq("commodityType",categoryName)).size()!=0)
        if (commodityInfoMapper.delete(new QueryWrapper<CommodityInfo>().eq("commodityType",categoryName))<=0)   throw new BusinessException(ResponseCode.UPDATE_ERROR,"更新失败");
        if (Objects.isNull(redisCache.getCacheObject("commodityInfo")))
        redisCache.deleteObject("commodityInfo");
        redisCache.deleteObject("AllCommodityList");
    }



    /**
     * @Description: 根据商品所选的商品id集合删除所有商品
     * @Param: int[] ids
     * @return: int
     * @Author: 黄燕峰
     */
    @Override
    public Response<String> deleteByIds(List<Integer> ids) {
        if (ids.size()==0)  throw new BusinessException(ResponseCode.UPDATE_ERROR, "传入数据为空");
        String kind = commodityInfoMapper.selectOne(new QueryWrapper<CommodityInfo>().eq("id", ids.get(0))).getCommodityType();
        commodityInfoMapper.selectBatchIds(ids).forEach(commodityInfo -> {
            deleteFlavorAndPrice(commodityInfo);
            int result = commodityInfoMapper.deleteById(commodityInfo.getId());

            if (result <= 0) throw new BusinessException(ResponseCode.UPDATE_ERROR, "更新失败");
        });

        if (Objects.isNull(redisCache.getCacheObject("commodityInfo"+kind))) redisCache.deleteObject("commodityInfo");
        redisCache.deleteObject("commodityInfo");
        redisCache.deleteObject("AllCommodityList");
        redisCache.deleteObject("categories");
        return ResultUtils.success(ResponseCode.SUCCESS,"更新成功");
    }

    /**
     * @Description: 获取所有商品
     * @Param: 无
     * @return: Response<Map<String,List<Commodity>>
     * @Author: 黄燕峰
     */
    @Override
    public Response<CommodityDetailVO> getCommodityDetail(Integer id) {
        CommodityInfo commodityInfo = commodityInfoMapper.selectOne(new QueryWrapper<CommodityInfo>().eq("id", id));
        CommodityDetailVO commodityDetailVO=new CommodityDetailVO();

        Flavor flavor = flavorMapper.selectOne(new LambdaQueryWrapper<Flavor>().eq(Flavor::getFlavorId, commodityInfo.getFlavorId()));



        List<Teabottom> teabottoms = null;
        List<String> temperature = null;
        List<String> sugar = null;
        final Map<String,BigDecimal> price = new HashMap<>();
        List<MixIngredients> mixIngredients = null;
        if (flavor != null) {
//            从flavor中取出scaleId封装到数组中
            String[] scaleIdsSpring = flavor.getScaleId().split(",");
            Integer[] scaleIds = new Integer[scaleIdsSpring.length];
            for (int i = 0; i < scaleIdsSpring.length; i++) {
                scaleIds[i] = Integer.parseInt(scaleIdsSpring[i]);
            }
//            根据数组中的每一个scaleId获取Scale集合
            List<Scale> scalesList = scaleMapper.selectByScaleIds(scaleIds);

//            获取商品中不同规格的价格




            scalesList.forEach(s -> {

                Price result = priceMapper.selectOne(new QueryWrapper<Price>().eq("scaleId", s.getScaleId()).eq("commodityId", commodityInfo.getId()));
                if (result != null) {

                    switch (s.getScale()){
                        case 0:
                            price.put("小",result.getPrice());
                            break;
                        case 1:
                            price.put("中",result.getPrice());
                            break;
                        case 2:
                            price.put("大",result.getPrice());
                            break;
                    }
                }
            });
//            对价格进行排序
//            price = list.stream().sorted().collect(Collectors.toList());


//            从flavor中取出teaId封装到数组中
            if (flavor.getTeaId() != null) {
                String[] teaIdsSpring = flavor.getTeaId().split(",");

                Integer[] teaId = new Integer[teaIdsSpring.length];
                for (int i = 0; i < teaIdsSpring.length; i++) {
                    teaId[i] = Integer.parseInt(teaIdsSpring[i]);
                }
                //            根据数组中的每一个teaId获取teaBottom集合
                teabottoms = teabottomMapper.selectByTeaIds(teaId);
            } else teabottoms = teabottomMapper.selectByTeaIds(null);


//            从flavor中取出ingredientId封装到数组中
            String[] ingredientIdSpring = flavor.getTeaId().split(",");
            Integer[] ingredientId = new Integer[ingredientIdSpring.length];
            for (int i = 0; i < ingredientIdSpring.length; i++) {
                ingredientId[i] = Integer.parseInt(ingredientIdSpring[i]);
            }
//            根据数组中的每一个ingredientId获取mixIngredients集合
            mixIngredients = mixIngredientsMapper.selectByIngredientIds(ingredientId);

//            将temperature分割封装到String集合
            temperature = Arrays.asList(flavor.getTemperature().split(","));
//            将sugar分割封装到String集合
            sugar = Arrays.asList(flavor.getSugar().split(","));

        }
        commodityDetailVO.setCommodityInfo(commodityInfo);
        commodityDetailVO.setPrice(price);
        commodityDetailVO.setSugar(sugar);
        commodityDetailVO.setTeaBottoms(teabottoms);

        commodityDetailVO.setTemperature(temperature);
        commodityDetailVO.setMixIngredients(mixIngredients);

        return ResultUtils.success(ResponseCode.SUCCESS,commodityDetailVO,null,"获取单个商品的详细信息");
    }


    public void deleteFlavorAndPrice(CommodityInfo commodityInfo) {
        if (commodityInfo==null) return;
        if (priceMapper.selectList(new QueryWrapper<Price>().eq("commodityId", commodityInfo.getId())).size() != 0) {
            if (priceMapper.delete(new QueryWrapper<Price>().eq("commodityId", commodityInfo.getId())) <= 0)
                throw new BusinessException(ResponseCode.UPDATE_ERROR, "更新失败");
        }
        if (flavorMapper.selectList(new QueryWrapper<Flavor>().eq("flavorId", commodityInfo.getFlavorId())).size() != 0) {
            if (flavorMapper.deleteById(commodityInfo.getFlavorId()) <= 0)
                throw new BusinessException(ResponseCode.UPDATE_ERROR, "更新失败");
            ;
        }
    }


}







